Calculando Oferta

Coletando os dados do CNES-PF

Primeiro, vamos calcular a oferta de médicos. Para isso, vamos selecionar os municípios solicitados: Jaú/SP, São Paulo/SP, Araripina/PE, Imperatriz/MA, Itabuna/BA, Itapipoca/CE, Estância/SE. Os médicos se inserem no CBO que se inicia em 225. Vamos acessar o mês de Dezembro de cada ano como referência para as análises.

consulta <- "SELECT CODUFMUN, CBO,
                     PROF_SUS, PROFNSUS, 
                     HORAOUTR, HORAHOSP, 
                     HORA_AMB, COMPETEN,
                     competencia 
              FROM Dados.cnes.PF
              WHERE (substr(CODUFMUN, 1, 6) = '355030' OR
                     substr(CODUFMUN, 1, 6) = '352530' OR
                     substr(CODUFMUN, 1, 6) = '260110' OR
                     substr(CODUFMUN, 1, 6) = '210530' OR
                     substr(CODUFMUN, 1, 6) = '291480' OR
                     substr(CODUFMUN, 1, 6) = '230640' OR
                     substr(CODUFMUN, 1, 6) = '280210') AND
                    (substr(CBO, 1, 3) = '225') AND 
              substr(COMPETEN, 5, 2) = '12' AND
              CAST(substr(COMPETEN, 1, 4) AS INTEGER) > 2009"


oferta <- sqlQuery(channel, consulta)

Full-Time equivalent

O próximo passo foi padronizar essa oferta em uma métrica chamada Full Time Equivalent (FTE), recomendação da própria Organização Mundial da Saúde devido à flexibilidade dos formatos de trabalho de profissionais de saúde.

oferta_fte <- 
        oferta %>% 
          mutate(hora_total = HORAOUTR + HORAHOSP + HORA_AMB) %>%
          mutate(sus = if_else(PROF_SUS == 1, "Prof_SUS","Nao_SUS")) %>% 
          group_by(CODUFMUN, sus, COMPETEN) %>% 
          summarise(horas = sum(hora_total)) %>% 
          mutate(fte40 = horas/40,
                 COMPETEN = as.character(COMPETEN),
                 ano = as.integer(substr(COMPETEN, 1, 4))) %>% 
          janitor::clean_names() %>% 
          select(ano, codufmun, sus, fte40) %>% 
          spread(sus, fte40) %>% 
          mutate(total = Prof_SUS + Nao_SUS)

Calculando Demanda

O cálculo da demanda por parâmetros de razão populacional. Tais parâmetros tiveram sua última atualização em 2021, estão institucionalizados na portaria de consolidação nº1 de 2017 do Ministério da Saúde e já são usados em ferramentas, como o EstimaSUS.

Acesando os dados de população nas projeções populacionais do IBGE

consulta2 <- "SELECT * FROM Dados.populacional.POPTBR"


pop <- sqlQuery(channel, consulta2)

Tratamentos adicionais à base de população.

pop <- 
  pop %>% 
  janitor::clean_names() %>% 
  mutate(munic_res = as.character(munic_res)) %>% 
  mutate(munic_res = substr(munic_res, 1, 6)) %>% 
  filter(munic_res == '355030' | munic_res == '352530' |
         munic_res == '260110' | munic_res == '210530' |
         munic_res == '291480' | munic_res == '230640' |
         munic_res == '280210')

Calculando a Demanda

A demanda é calculada a partir de parâmetros sobre a população.

demanda <- pop %>% 
              janitor::clean_names() %>% 
              mutate(medico_familia = populacao/2000,
                     medico_clinico_geral = populacao/4184,
                     medico_gineco = populacao/4597,
                     medico_pediatra = populacao/3616,
                     medico_acupunt = populacao/100000,
                     medico_alerg = populacao/100000,
                     medico_angio = populacao/33333,
                     medico_cirurg_geral = populacao/6451,
                     medico_cirurg_ped = populacao/50000,
                     medico_cirurg_plast = populacao/50000,
                     medico_coloprocto = populacao/50000,
                     medico_dermato = populacao/43478,
                     medico_endocrino = populacao/66666,
                     medico_gastro = populacao/40000,
                     medico_geriatra = populacao/100000,
                     medico_hemato = populacao/100000,
                     medico_homeo = populacao/100000,
                     medico_infect = populacao/100000,
                     medico_mast = populacao/100000,
                     medico_nefro = populacao/38461,
                     medico_neuro = populacao/21276,
                     medico_oftalmo = populacao/20000,
                     medico_ortop = populacao/10000,
                     medico_otorrino = populacao/33333,
                     medico_pneumo = populacao/33333,
                     medico_psiq = populacao/17241,
                     medico_reumato = populacao/100000,
                     medico_uro = populacao/33333,
                     medico_trab = populacao/100000,
                     medico_anest = populacao/10000,
                     medico_cirurg_dig = populacao/50000,
                     medico_cirurg_cp = populacao/100000,
                     medico_cirurg_tx = populacao/100000,
                     medico_cirurg_cv = populacao/100000,
                     medico_genet = populacao/400000,
                     medico_hemot = populacao/200000,
                     medico_nuclear = populacao/200000,
                     medico_onco = populacao/33333,
                     medico_intens = populacao/33333,
                     medico_outras = populacao/2000)

Como o nível de análise é categoria e não especialidade, somaremos todas as especialidades para acessar a demanda geral.

demanda$demanda <- rowSums(demanda[,4:43])

Juntando demanda e oferta

demanda_oferta <- demanda %>% 
  select(munic_res, ano, populacao, demanda) %>% 
  mutate(munic_res = as.integer(munic_res)) %>% 
  left_join(oferta_fte, by = c("ano","munic_res"="codufmun")) %>% 
  filter(total != "NA") %>% 
  mutate(resultado = total - demanda) %>% 
  left_join(hierarquia_municipios, by = c("munic_res" = "cod_municipio"))

Visualizando resultados

O gráfico a seguir apresenta os valores de demanda e oferta. A linha verde representa a oferta enquanto que a linha azul é a demanda que seria necessária naquele local, considerando os parâmetros de razão populacional.

a <- demanda_oferta %>% 
  ggplot(aes(x = ano)) + geom_line(aes(y = demanda), col = "blue") + 
  geom_line(aes(y = total), col = "darkgreen") + facet_wrap(~municipio, scales = "free") + 
  theme_minimal() 

plotly::ggplotly(a)
tabela <- 
  demanda_oferta %>% 
  select(ano, municipio, uf, populacao, demanda, Nao_SUS, Prof_SUS, total) %>% 
  mutate(demanda = round(demanda,2)) %>% 
  rename(oferta = total)

DT::datatable(tabela)

Dados de plano de saúde

Acessando dados

Vamos acessar os dados de plano de saúde. Vamos pegar como referência o mês de dezembro de cada ano.

consulta3 <- "SELECT ID_CMPT, SUBSTR(ID_CMPT, 1, 4) AS ANO,
                     SG_UF, CD_MUNICIP, SUM(CAST(NR_BENEF_T AS INT)) AS TOTAL_BENEF
              FROM Dados.ans_municipios.tb_bb
              WHERE
                  (substr(CD_MUNICIP, 1, 6) = '355030' OR
                                   substr(CD_MUNICIP, 1, 6) = '352530' OR
                                   substr(CD_MUNICIP, 1, 6) = '260110' OR
                                   substr(CD_MUNICIP, 1, 6) = '210530' OR
                                   substr(CD_MUNICIP, 1, 6) = '291480' OR
                                   substr(CD_MUNICIP, 1, 6) = '230640' OR
                                   substr(CD_MUNICIP, 1, 6) = '280210')
                  AND substr(ID_CMPT, 5, 2) = '12'
              GROUP BY ID_CMPT, SG_UF, CD_MUNICIP"

ans <- sqlQuery(channel, consulta3)

Calculando a cobertura

Vamos juntar os planos de saúde e a população para calcularmos a cobertura de plano de saúde, por meio da divisão do número de beneficiários e população.

hierarquia_municipios$cod_municipio <- as.character(hierarquia_municipios$cod_municipio)


cobertura <- 
  ans %>% 
  filter(ANO > 2009) %>% 
  mutate(CD_MUNICIP = as.character(CD_MUNICIP)) %>% 
  left_join(pop, by = c("ANO"="ano","CD_MUNICIP"="munic_res")) %>% 
  mutate(cobertura = (TOTAL_BENEF/populacao) * 100) %>% 
  left_join(hierarquia_municipios, by = c("CD_MUNICIP"="cod_municipio"))

Visualizando resultados

b <- cobertura %>% 
  ggplot(aes(x = ANO, y = cobertura)) + geom_line() + 
  facet_wrap(~municipio, scales = "free") + 
  theme_minimal() 


plotly::ggplotly(b)
cobertura2 <- cobertura %>% 
                select(ANO, municipio, populacao, TOTAL_BENEF, cobertura) %>% 
                mutate(cobertura = round(cobertura, 2)) %>% 
                janitor::clean_names()


DT::datatable(cobertura2)